﻿using BoriPeter.FitnessJournal8.DAL;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BoriPeter.FitnessJournal8.Models
{
    public class Serving : ModelBase
    {
        #region Id
        /* the unique serving identifier. */
        private int id;
        public int Id
        {
            get
            {
                return this.id;
            }

            set
            {
                this.id = value;
                NotifyOfPropertyChange("Id");
            }
        }
        #endregion

        #region Description
        /* the full description of the serving size. E.G.: "1 cup" or "100 g". */
        private string description;
        public string Description
        {
            get
            {
                return this.description;
            }

            set
            {
                this.description = value;
                NotifyOfPropertyChange("Description");
            }
        }
        #endregion

        #region Url
        /* URL of the serving size for this food item on www.fatsecret.com. */
        private string url;
        public string Url
        {
            get
            {
                return this.url;
            }

            set
            {
                this.url = value;
                NotifyOfPropertyChange("Url");
            }
        }
        #endregion

        #region MetricUnit
        private string metricUnit;
        public string MetricUnit
        {
            get
            {
                return this.metricUnit;
            }

            set
            {
                this.metricUnit = value;
                NotifyOfPropertyChange("MetricUnit");
            }
        }
        #endregion

        #region MetricNumberOfUnits
        private decimal metricNumberOfUnits;
        public decimal MetricNumberOfUnits
        {
            get
            {
                return this.metricNumberOfUnits;
            }

            set
            {
                this.metricNumberOfUnits = value;
                NotifyOfPropertyChange("MetricNumberOfUnits");
            }
        }
        #endregion

        #region UnitOfMeasure
        /* the metric unit of measure for the serving size – either "g" or "ml" or "oz" –
        * combined with metric_serving_amount to derive the total standardized 
        * quantity of the serving (where available).*/
        private string unitOfMeasure;
        public string UnitOfMeasure
        {
            get
            {
                return this.unitOfMeasure;
            }

            set
            {
                this.unitOfMeasure = value;
                NotifyOfPropertyChange("UnitOfMeasure");
            }
        }
        #endregion

        #region NumberOfUnits
        /* the number of units in this standard serving size. For instance, if the serving 
         * description is "2 tablespoons" the number of units is "2", while if the serving 
         * size is "1 cup" the number of units is "1". */
        private decimal numberOfUnits;
        public decimal NumberOfUnits
        {
            get
            {
                return this.numberOfUnits;
            }

            set
            {
                this.numberOfUnits = value;
                NotifyOfPropertyChange("NumberOfUnits");
            }
        }
        #endregion

        #region MeasurementDescription
        private string measurementDescription;
        public string MeasurementDescription
        {
            get
            {
                return this.measurementDescription;
            }

            set
            {
                this.measurementDescription = value;
                NotifyOfPropertyChange("MeasurementDescription");
            }
        }
        #endregion

        #region Calories
        /* the energy content in kcal. */
        private decimal caloriesKcal;
        public decimal CaloriesKcal
        {
            get
            {
                return this.caloriesKcal;
            }

            set
            {
                this.caloriesKcal = value;
                NotifyOfPropertyChange("CaloriesKcal");

                this.caloriesRDI = RDIConverter.Unit2RDI(RDIConverter.RDI_CALORIES_KCAL, value);
                NotifyOfPropertyChange("CaloriesRDI");
            }
        }

        private decimal caloriesRDI;
        public decimal CaloriesRDI
        {
            get
            {
                return this.caloriesRDI;
            }

            set
            {
                this.caloriesRDI = value;
                NotifyOfPropertyChange("CaloriesRDI");

                this.caloriesKcal = RDIConverter.RDI2Unit(RDIConverter.RDI_CALORIES_KCAL, value);
                NotifyOfPropertyChange("CaloriesKcal");
            }
        }
        #endregion

        #region Carbohydrate
        /* the total carbohydrate content in grams. */
        private decimal carbohydrateGram;
        public decimal CarbohydrateGram
        {
            get
            {
                return this.carbohydrateGram;
            }

            set
            {
                this.carbohydrateGram = value;
                NotifyOfPropertyChange("CarbohydrateGram");

                this.carbohydrateRDI = RDIConverter.Unit2RDI(RDIConverter.RDI_CARBOHYDRATE_GRAM, value);
                NotifyOfPropertyChange("CarbohydrateRDI");

                UpdateCalorieBreakdown();
            }
        }

        private decimal carbohydrateRDI;
        public decimal CarbohydrateRDI
        {
            get
            {
                return this.carbohydrateRDI;
            }

            set
            {
                this.carbohydrateRDI = value;
                NotifyOfPropertyChange("CarbohydrateRDI");

                this.carbohydrateGram = RDIConverter.RDI2Unit(RDIConverter.RDI_CARBOHYDRATE_GRAM, value);
                NotifyOfPropertyChange("CarbohydrateGram");

                UpdateCalorieBreakdown();
            }
        }
        #endregion

        #region Protein
        /* the protein content in grams. */
        private decimal proteinGram;
        public decimal ProteinGram
        {
            get
            {
                return this.proteinGram;
            }

            set
            {
                this.proteinGram = value;
                NotifyOfPropertyChange("ProteinGram");

                this.proteinRDI = RDIConverter.Unit2RDI(RDIConverter.RDI_PROTEIN_GRAM, value);
                NotifyOfPropertyChange("ProteinRDI");

                UpdateCalorieBreakdown();
            }
        }

        private decimal proteinRDI;
        public decimal ProteinRDI
        {
            get
            {
                return this.proteinRDI;
            }

            set
            {
                this.proteinRDI = value;
                NotifyOfPropertyChange("ProteinRDI");

                this.proteinGram = RDIConverter.RDI2Unit(RDIConverter.RDI_PROTEIN_GRAM, value);
                NotifyOfPropertyChange("ProteinGram");

                UpdateCalorieBreakdown();
            }
        }
        #endregion

        #region Fat
        private decimal fatGram;
        public decimal FatGram
        {
            get
            {
                return this.fatGram;
            }

            set
            {
                this.fatGram = value;
                NotifyOfPropertyChange("FatGram");

                this.fatRDI = RDIConverter.Unit2RDI(RDIConverter.RDI_TOTAL_FAT_GRAM, value);
                NotifyOfPropertyChange("FatRDI");

                UpdateCalorieBreakdown();
            }
        }

        /* the total fat content in grams. */
        private decimal fatRDI;
        public decimal FatRDI
        {
            get
            {
                return this.fatRDI;
            }

            set
            {
                this.fatRDI = value;
                NotifyOfPropertyChange("FatRDI");

                this.fatGram = RDIConverter.RDI2Unit(RDIConverter.RDI_TOTAL_FAT_GRAM, value);
                NotifyOfPropertyChange("FatGram");

                UpdateCalorieBreakdown();
            }
        }
        #endregion

        #region SaturatedFat
        /* the saturated fat content in grams (where available). */
        private decimal saturatedFatGram;
        public decimal SaturatedFatGram
        {
            get
            {
                return this.saturatedFatGram;       
            }

            set
            {
                this.saturatedFatGram = value;
                NotifyOfPropertyChange("SaturatedFatGram");
            }
        }
        #endregion

        #region PolyunsaturatedFat
        /* the polyunsaturated fat content in grams (where available). */
        private decimal polyunsaturatedFatGram;
        public decimal PolyunsaturatedFatGram
        {
            get
            {
                return this.polyunsaturatedFatGram;
            }

            set
            {
                this.polyunsaturatedFatGram = value;
                NotifyOfPropertyChange("PolyunsaturatedFatGram");
            }
        }
        #endregion

        #region MonosaturatedFat
        /* the monounsaturated fat content in grams (where available). */
        private decimal monosaturatedFatGram;
        public decimal MonosaturatedFatGram
        {
            get
            {
                return this.monosaturatedFatGram;
            }

            set
            {
                this.monosaturatedFatGram = value;
                NotifyOfPropertyChange("MonosaturatedFatGram");
            }
        }
        #endregion

        #region TransFat
        /* the trans fat content in grams (where available). */
        private decimal transFatGram;
        public decimal TransFatGram
        {
            get
            {
                return this.transFatGram;
            }

            set
            {
                this.transFatGram = value;
                NotifyOfPropertyChange("TransFatGram");
            }
        }
        #endregion

        #region Cholesterol
        /* cholesterol is a Decimal – the cholesterol content in milligrams (where available). */
        private decimal cholesterolMg;
        public decimal CholesterolMg
        {
            get
            {
                return this.cholesterolMg;
            }

            set
            {
                this.cholesterolMg = value;
                NotifyOfPropertyChange("CholesterolMg");

                this.cholesterolRDI = RDIConverter.Unit2RDI(RDIConverter.RDI_CHOLESTEROL_MG, value);
                NotifyOfPropertyChange("CholesterolRDI");
            }
        }

        private decimal cholesterolRDI;
        public decimal CholesterolRDI
        {
            get
            {
                return this.cholesterolRDI;
            }

            set
            {
                this.cholesterolRDI = value;
                NotifyOfPropertyChange("CholesterolRDI");

                this.cholesterolMg = RDIConverter.RDI2Unit(RDIConverter.RDI_CHOLESTEROL_MG, value);
                NotifyOfPropertyChange("CholesterolMg");
            }
        }
        #endregion

        #region Sodium
        /* the sodium content in milligrams (where available). */
        private decimal sodiumMg;
        public decimal SodiumMg
        {
            get
            {
                return this.sodiumMg;
            }

            set
            {
                this.sodiumMg = value;
                NotifyOfPropertyChange("SodiumMg");

                this.sodiumRDI = RDIConverter.Unit2RDI(RDIConverter.RDI_SODIUM_MG, value);
                NotifyOfPropertyChange("SodiumRDI");
            }
        }

        private decimal sodiumRDI;
        public decimal SodiumRDI
        {
            get
            {
                return this.sodiumRDI;
            }

            set
            {
                this.sodiumRDI = value;
                NotifyOfPropertyChange("SodiumRDI");

                this.sodiumMg = RDIConverter.RDI2Unit(RDIConverter.RDI_SODIUM_MG, value);
                NotifyOfPropertyChange("SodiumMg");
            }
        }
        #endregion

        #region Potassium
        /* the potassium content in milligrams (where available). */
        private decimal potassiumMg;
        public decimal PotassiumMg
        {
            get
            {
                return this.potassiumMg;
            }

            set
            {
                this.potassiumMg = value;
                NotifyOfPropertyChange("PotassiumMg");

                this.potassiumRDI = RDIConverter.Unit2RDI(RDIConverter.RDI_POTASSIUM_MG, value);
                NotifyOfPropertyChange("PotassiumRDI");
            }
        }

        private decimal potassiumRDI;
        public decimal PotassiumRDI
        {
            get
            {
                return this.potassiumRDI;
            }

            set
            {
                this.potassiumRDI = value;
                NotifyOfPropertyChange("PotassiumRDI");

                this.potassiumMg = RDIConverter.RDI2Unit(RDIConverter.RDI_POTASSIUM_MG, value);
                NotifyOfPropertyChange("PotassiumMg");
            }
        }
        #endregion

        #region Fiber
        /* the fiber content in grams (where available). */
        private decimal fiberGram;
        public decimal FiberGram
        {
            get
            {
                return this.fiberGram;
            }

            set
            {
                this.fiberGram = value;
                NotifyOfPropertyChange("FiberGram");

                this.fiberRDI = RDIConverter.Unit2RDI(RDIConverter.RDI_FIBER_GRAM, value);
                NotifyOfPropertyChange("FiberRDI");
            }
        }

        private decimal fiberRDI;
        public decimal FiberRDI
        {
            get
            {
                return this.fiberRDI;
            }

            set
            {
                this.fiberRDI = value;
                NotifyOfPropertyChange("FiberRDI");

                this.fiberGram = RDIConverter.RDI2Unit(RDIConverter.RDI_FIBER_GRAM, value);
                NotifyOfPropertyChange("FiberGram");
            }
        }
        #endregion

        #region Sugar
        /* the sugar content in grams (where available). */
        private decimal sugarGram;
        public decimal SugarGram
        {
            get
            {
                return this.sugarGram;
            }

            set
            {
                this.sugarGram = value;
                NotifyOfPropertyChange("SugarGram");
            }
        }
        #endregion

        #region VitaminA
        private decimal vitaminAUg;
        public decimal VitaminAUg
        {
            get
            {
                return this.vitaminAUg;
            }

            set
            {
                this.vitaminAUg = value;
                NotifyOfPropertyChange("VitaminAUg");

                this.vitaminARDI = RDIConverter.Unit2RDI(RDIConverter.RDI_VITAMIN_A_UG, value);
                NotifyOfPropertyChange("VitaminARDI");
            }
        }

        /* the percentage of daily recommended Vitamin A, based on a 2000 calorie diet (where available). */
        private decimal vitaminARDI;
        public decimal VitaminARDI
        {
            get
            {
                return this.vitaminARDI;
            }

            set
            {
                this.vitaminARDI = value;
                NotifyOfPropertyChange("VitaminARDI");

                this.vitaminAUg = RDIConverter.RDI2Unit(RDIConverter.RDI_VITAMIN_A_UG, value);
                NotifyOfPropertyChange("VitaminAUg");
            }
        }
        #endregion

        #region VitaminC
        private decimal vitaminCMg;
        public decimal VitaminCMg
        {
            get
            {
                return this.vitaminCMg;
            }

            set
            {
                this.vitaminCMg = value;
                NotifyOfPropertyChange("VitaminCMg");

                this.vitaminCRDI = RDIConverter.Unit2RDI(RDIConverter.RDI_VITAMIN_C_MG, value);
                NotifyOfPropertyChange("VitaminCRDI");
            }
        }

        /* the percentage of daily recommended Vitamin C, based on a 2000 calorie diet (where available). */
        private decimal vitaminCRDI;
        public decimal VitaminCRDI
        {
            get
            {
                return this.vitaminCRDI;
            }

            set
            {
                this.vitaminCRDI = value;
                NotifyOfPropertyChange("VitaminCRDI");

                this.vitaminCMg = RDIConverter.RDI2Unit(RDIConverter.RDI_VITAMIN_C_MG, value);
                NotifyOfPropertyChange("VitaminCMg");
            }
        }
        #endregion

        #region Calcium
        private decimal calciumMg;
        public decimal CalciumMg
        {
            get
            {
                return this.calciumMg;
            }

            set
            {
                this.calciumMg = value;
                NotifyOfPropertyChange("CalciumMg");

                this.calciumRDI = RDIConverter.Unit2RDI(RDIConverter.RDI_CALCIUM_MG, value);
                NotifyOfPropertyChange("CalciumRDI");
            }
        }

        /* the percentage of daily recommended Calcium, based on a 2000 calorie diet (where available). */
        private decimal calciumRDI;
        public decimal CalciumRDI
        {
            get
            {
                return this.calciumRDI;
            }

            set
            {
                this.calciumRDI = value;
                NotifyOfPropertyChange("CalciumRDI");

                this.calciumMg = RDIConverter.RDI2Unit(RDIConverter.RDI_CALCIUM_MG, value);
                NotifyOfPropertyChange("CalciumMg");
            }
        }
        #endregion

        #region Iron
        private decimal ironMg;
        public decimal IronMg
        {
            get
            {
                return this.ironMg;
            }

            set
            {
                this.ironMg = value;
                NotifyOfPropertyChange("IronMg");

                this.ironRDI = RDIConverter.Unit2RDI(RDIConverter.RDI_IRON_MG, value);
                NotifyOfPropertyChange("IronRDI");
            }
        }

        /* the percentage of daily recommended Iron, based on a 2000 calorie diet (where available). */
        private decimal ironRDI;
        public decimal IronRDI
        {
            get
            {
                return this.ironRDI;
            }

            set
            {
                this.ironRDI = value;
                NotifyOfPropertyChange("IronRDI");

                this.ironMg = RDIConverter.RDI2Unit(RDIConverter.RDI_IRON_MG, value);
                NotifyOfPropertyChange("IronMg");
            }
        }
        #endregion

        #region CalorieBreakdown
        private ObservableCollection<NameValuePair> calorieBreakdown;
        public ObservableCollection<NameValuePair> CalorieBreakdown
        {
            get
            {
                if (calorieBreakdown == null)
                    UpdateCalorieBreakdown();
                return this.calorieBreakdown;
            }

            set
            {
                this.calorieBreakdown = value;
                NotifyOfPropertyChange("CalorieBreakdown");
            }
        }
        #endregion

        #region UpdateCalorieBreakdown()
        private void UpdateCalorieBreakdown()
        {
            var cb = new ObservableCollection<NameValuePair>();

            if (CarbohydrateGram != 0)
                cb.Add(new NameValuePair() { Name = CARBOHYDRATE, Value = float.Parse(CarbohydrateGram.ToString()) });

            if (FatGram != 0)
                cb.Add(new NameValuePair() { Name = FAT, Value = float.Parse(FatGram.ToString()) });

            if (ProteinGram != 0)
                cb.Add(new NameValuePair() { Name = PROTEIN, Value = float.Parse(ProteinGram.ToString()) } );

            CalorieBreakdown = cb;
        }
        #endregion
    }
}
